#pragma once
#include "SkypeClient.h"
#include "SkypeAPICtrl.h"
#include "CallingData.h"
#include <string>
#include <set>
#include <map>
using namespace std;

class ClientsManagerObserver {
public:
	virtual void clientLogined(const SkypeClient* client) = 0;
	virtual void clientOnline(const SkypeClient* client) = 0;
	virtual void clientTimeOut(const SkypeClient* client) = 0;
	virtual void clientCallRefused(const SkypeClient* client) = 0;
	virtual void clientCallFailed(const SkypeClient* client) = 0;
	virtual void clientCallBusy(const SkypeClient* client) = 0;
	virtual void clientCallMissed(const SkypeClient* client) = 0;
	virtual void clientCallFinished(const SkypeClient* client) = 0;
};

DWORD WINAPI WatchDog(LPVOID lpParameter);
class ClientsManager {
public:
	ClientsManager(void);
	~ClientsManager(void);

	SkypeAPICtrl* apiCtrl() {
		return &m_apiCtrl;
	}

	// client list
	void addClient(SkypeClient* client) {
	}
	void removeClient(SkypeClient* client) {
	}
	void scanClients();
	void listClients();

	// clients actions

	// client events
	void clientLogined(const SkypeClient* client);
	void clientOnline(const SkypeClient* client);
	void clientTimeOut(const SkypeClient* client);
	void clientCallRefused(const SkypeClient* client);
	void clientCallFailed(const SkypeClient* client);
	void clientCallBusy(const SkypeClient* client);
	void clientCallMissed(const SkypeClient* client);
	void clientCallFinished(const SkypeClient* client);

	// api ctrl events
	void attachApiAvailable(SkypeAPICtrl* apiCtrl);
	void attachApiRefused(SkypeAPICtrl* apiCtrl);
	void attachApiNotAvailable(SkypeAPICtrl* apiCtrl);
	void attachApiAuthPending(SkypeAPICtrl* apiCtrl);
	void attachApiSuccess(SkypeAPICtrl* apiCtrl, HWND ctrlWin);
	void attachApiMessage(SkypeAPICtrl* apiCtrl, HWND ctrlWin,
			PCOPYDATASTRUCT msgData);

	// manager interface
	void addObserver(ClientsManagerObserver* observer);
	void removeObserver(ClientsManagerObserver* observer);
	SkypeClient* makeCall(const string& callerId, const string& callerPwd,
			const string& calleeId);
	void run();
	void stop();
private:
	string procName(DWORD processID);
	SkypeClient* findClientbyWin(HWND win);
private:
	// process id, client
	map<DWORD, SkypeClient*> m_clients; // SkypeClient* owned
	SkypeAPICtrl m_apiCtrl;
	set<ClientsManagerObserver*> m_observers; // * not owned
	CRITICAL_SECTION m_clientsCriticalSection;

	volatile bool m_isRun;
	volatile time_t m_lastCallTime;
	HANDLE m_watchDogThread;

	friend DWORD WINAPI WatchDog(LPVOID lpParameter);
};
